package com.zw.cloud.common.utils.weixin;

import org.apache.commons.codec.binary.Base64;

import java.util.Objects;
import java.util.UUID;

public class WeChatAesUtils {

    public static final String encodingAesKey = "YVfgOzNebC8tCDIVZxabalnQS550lUgSEtXuUFYuPHN";
    public static final String token = "zhengwei";
    public static final String appId = "wx38237281a69df8d4";

    private static volatile WXBizMsgCrypt wxBizMsgCrypt;

    public static final String robotEncodingAesKey = "it9gcR9E16C3YkittoyQexIAJGeUPvckTLR5Jm1BhSf";
    public static final String robotToken = "B6NFmZ4QZywZm02raQ1hBG2v76hIfw";
    public static final String robotAppId = "ZQollJNVXOHpHBQ";

    private static volatile WXBizMsgCrypt wxRobotBizMsgCrypt;

    /**
     * 检验消息的真实性，并且获取解密后的明文.
     * <ol>
     * 	<li>利用收到的密文生成安全签名，进行签名验证</li>
     * 	<li>若验证通过，则提取xml中的加密消息</li>
     * 	<li>对消息进行解密</li>
     * </ol>
     *
     * @param msgSignature 签名串，对应URL参数的msg_signature
     * @param timeStamp 时间戳，对应URL参数的timestamp
     * @param nonce 随机串，对应URL参数的nonce
     * @param postData 密文，对应POST请求的数据
     *
     * @return 解密后的原文
     * @throws AesException 执行失败，请查看该异常的错误码和具体的错误信息
     */
    public static String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData) throws AesException {
        return getWXBizMsgCrypt().decryptMsg(msgSignature, timeStamp, nonce, postData);
    }

    /**
     * 将公众平台回复用户的消息加密打包.
     * <ol>
     * 	<li>对要发送的消息进行AES-CBC加密</li>
     * 	<li>生成安全签名</li>
     * 	<li>将消息密文和安全签名打包成xml格式</li>
     * </ol>
     *
     * @param replyMsg 公众平台待回复用户的消息，xml格式的字符串
     * @param timeStamp 时间戳，可以自己生成，也可以用URL参数的timestamp
     * @param nonce 随机串，可以自己生成，也可以用URL参数的nonce
     *
     * @return 加密后的可以直接回复用户的密文，包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
     * @throws AesException 执行失败，请查看该异常的错误码和具体的错误信息
     */
    public static String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
        return getWXBizMsgCrypt().encryptMsg(replyMsg, timeStamp, nonce);
    }

    /**
     * 直接解密 密文,不进行签名校验
     */
    public static String decryptRobotMsg(String replyMsg) throws AesException {
        return getWXRobotBizMsgCrypt().decrypt(replyMsg);
    }

    private static WXBizMsgCrypt getWXBizMsgCrypt() throws AesException {
        if (Objects.isNull(wxBizMsgCrypt)) {
            synchronized (WeChatAesUtils.class) {
                if (Objects.isNull(wxBizMsgCrypt)) {
                    // IllegalArgumentException: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value. Expected the discarded bits to be zero.
                    // 替换 encodingAesKey  Base64.encodeBase64String(UUID.randomUUID().toString().replaceAll("-", "").getBytes())
                    wxBizMsgCrypt = new WXBizMsgCrypt(token, encodingAesKey, appId);
                }
            }
        }
        return wxBizMsgCrypt;
    }

    private static WXBizMsgCrypt getWXRobotBizMsgCrypt() throws AesException {
        if (Objects.isNull(wxRobotBizMsgCrypt)) {
            synchronized (WeChatAesUtils.class) {
                if (Objects.isNull(wxRobotBizMsgCrypt)) {
                    // IllegalArgumentException: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value. Expected the discarded bits to be zero.
                    // 使用 commons-codec 1.9版本  或者 替换 encodingAesKey  Base64.encodeBase64String(UUID.randomUUID().toString().replaceAll("-", "").getBytes())
                    wxRobotBizMsgCrypt = new WXBizMsgCrypt(robotToken, robotEncodingAesKey, robotAppId);
                }
            }
        }
        return wxRobotBizMsgCrypt;
    }

    public static void main(String[] args) throws AesException {
        System.out.println(Base64.encodeBase64String(UUID.randomUUID().toString().replaceAll("-", "").getBytes()));
    }
}
